/*
* observe:数据监听器，通过该监听器可以实现对数据状态的监听。一旦数据发生变化，通过发布者通知订阅者。
* compile:元素编译器，对元素进行解析，可以根据元素与数据状态之间的关联，可以通过wather创建订阅者
* 每一个数据状态都可以对应多个订阅者，每个订阅者的职责是更新视图。
* */

function Zhang(options={}){
    this.$options = options;// 记录配置信息
    // 根据options.el获取挂载的元素
    this.$el = document.querySelector(options.el);
    this.$data = options.data;
    this.$binds = {};// {str:[订阅者，订阅者],a:[],b:[]}
    for(let key in options.methods){
        this[key]=options.methods[key];
    }
    this.observe();
    this.compile(this.$el);
}
// 监听器：监听数据是否发生变化，如果发生变化，发布消息（通过订阅者）
Zhang.prototype.observe = function(){
    for(let key in this.$data){
        this.$binds[key] = [];
        Object.defineProperty(this,key,{
            get(){
                return this.$data[key];
            },
            set(v){
                this.$data[key] = v;
                this.$binds[key].forEach((item)=>{
                    item.call(this);
                })
            }
        })
    }

}
// 编译器：编译模板--》识别指令
Zhang.prototype.compile = function(el){
    // 获取VUE挂载元素的所有子元素
    const nodes = el.children;
    for(let i=0;i<nodes.length;i++){
        const node = nodes[i];
        this.compile(node);
        // 判断元素是否拥有z-model属性
        if(node.hasAttribute("z-model")){
            // 将元素的value属性设置为：状态下的与z-model属性值相同的属性
            // 获取属性值
            const attrValue = node.getAttribute("z-model");
            node.addEventListener("input",()=>{
                this[attrValue] = node.value
            })
            node.value = this[attrValue];

            // 增加订阅者
            this.$binds[attrValue].push(function(){
                node.value = this[attrValue]
            })





            // nodes[i].value =
        }
        if(node.hasAttribute("z-on:click")){
            const attrValue = node.getAttribute("z-on:click");
            node.addEventListener("click",this[attrValue].bind(this));
        }
        if(node.hasAttribute("z-html")){
            // 获取属性值
            const attrValue = node.getAttribute("z-html");
            node.innerHTML = this[attrValue];
            this.$binds[attrValue].push(function(){
                node.innerHTML =  this[attrValue];
            })
        }
        if(node.hasAttribute("z-text")){
            // 获取属性值
            const attrValue = node.getAttribute("z-text");
            node.innerText = this[attrValue];
            this.$binds[attrValue].push(function(){
                node.innerText =  this[attrValue];
            })
        }
    }
}
// 意念式编程